package com.happyfamily.springboot.crowdsourcingplatform.aop;

import com.alibaba.fastjson.JSON;
import com.happyfamily.springboot.crowdsourcingplatform.annotation.OperationLogDetail;
import com.happyfamily.springboot.crowdsourcingplatform.model.OperationLog;
import com.happyfamily.springboot.crowdsourcingplatform.model.SysUser;
import com.happyfamily.springboot.crowdsourcingplatform.service.weng.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Aspect
@Component
public class LogAspect
{

	@Autowired
	private LogService logService;

	@Autowired
	private HttpServletRequest httpServletRequest;

	/**
	 * 此处的切点是注解的方式，也可以用包名的方式达到相同的效果
	 * '@Pointcut("execution(* com.wwj.springboot.service.impl.*.*(..))")'
	 */
	@Pointcut("@annotation(com.happyfamily.springboot.crowdsourcingplatform.annotation.OperationLogDetail)")
	public void operationLog()
	{
	}


	/**
	 * 环绕增强，相当于MethodInterceptor
	 */
	@Around("operationLog()")
	public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable
	{
		Object res = null;
		long time = System.currentTimeMillis();
		try
		{
			res = joinPoint.proceed();
			time = System.currentTimeMillis() - time;
			return res;
		} finally
		{
			try
			{
				//方法执行完成后增加日志
				addOperationLog(joinPoint, res, time);
			} catch (Exception e)
			{
				System.out.println("LogAspect 操作失败：" + e.getMessage());
				e.printStackTrace();
			}
		}
	}

	private void addOperationLog(JoinPoint joinPoint, Object res, long time)
	{
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		OperationLog operationLog = new OperationLog();
		SecurityContextImpl securityContext = (SecurityContextImpl) httpServletRequest.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
		operationLog.setRunTime(time);
		if (res != null)
		{
			operationLog.setReturnValue(JSON.toJSONString(res));
		} else
		{
			operationLog.setReturnValue("[]");

		}
		operationLog.setArgs("[涉及私密信息无权限查看]");
		operationLog.setCreateTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
		operationLog.setMethod(signature.getName());
		if (securityContext != null)
		{
			operationLog.setUserId(securityContext.getAuthentication().getName());
		} else
		{
			operationLog.setUserId("游客");
		}
		OperationLogDetail annotation = signature.getMethod().getAnnotation(OperationLogDetail.class);
		if (annotation != null)
		{
			operationLog.setLogLevel(annotation.level());
			operationLog.setLogDescribe(annotation.detail());
			operationLog.setOperationType(annotation.operationType().getValue());
			operationLog.setOperationUnit(annotation.operationUnit().getValue());
		}
		//TODO 这里保存日志
		logService.insert(operationLog);
	}
}
